package com.sleepapp.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sleepapp.dao.ProductDao;
import com.sleepapp.dao.UserDao;
import com.sleepapp.dto.exception.CustomizeException;
import com.sleepapp.entity.Product;
import com.sleepapp.entity.RedemptionRecord;
import com.sleepapp.dao.RedemptionRecordDao;
import com.sleepapp.entity.User;
import com.sleepapp.service.RedemptionRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sleepapp.utils.AjaxResult;
import com.sleepapp.utils.StpUserUtil;
import com.sleepapp.vo.PageQueryInfo;
import com.sleepapp.vo.PageQueryParamVo;
import com.sleepapp.vo.RecordQueryAllVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 兑换记录表 服务实现类
 * </p>
 *
 * @author 
 * @since 2025-03-13
 */
@Service
@Slf4j
public class RedemptionRecordServiceImpl extends ServiceImpl<RedemptionRecordDao, RedemptionRecord> implements RedemptionRecordService {

    @Autowired
    private ProductDao productDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult<Void> add(Long id) {
        long userId = StpUserUtil.getLoginIdAsLong();
        String redisKey = "product:exchange:" + userId;
        try {
            if (Boolean.FALSE.equals(stringRedisTemplate.opsForValue().setIfAbsent(redisKey, "1"))) {
                throw new CustomizeException("操作速度过快!");
            }

            stringRedisTemplate.expire(redisKey,5L, TimeUnit.SECONDS);

            // 是否有这个商品
            Product product = productDao.selectById(id);
            // 商品是否冻结
            if (product == null || product.getStatus().equals("FROZEN")) {
                return AjaxResult.fail("商品不存在或已冻结");
            }

            // 库存是否足够
            if (product.getStock() <= 0) {
                return AjaxResult.fail("商品已售罄");
            }

            User user = userDao.selectById(userId);

            // 用户积分是否足够
            if (user.getPoints() < product.getPoints()) {
                return AjaxResult.fail("积分不足");
            }

            // 添加兑换记录
            RedemptionRecord redemptionRecord = new RedemptionRecord();
            redemptionRecord.setUserId(userId);
            redemptionRecord.setProductId(id);
            redemptionRecord.setPointsUsed(product.getPoints());
            if (!this.save(redemptionRecord)) {
                throw new CustomizeException("添加兑换记录失败");
            }

            // 扣减用户积分
            user.setPoints(user.getPoints() - product.getPoints());

            if (userDao.updateById(user) == 0) {
                throw new CustomizeException("更新用户积分失败");
            }

            // 扣减库存
            product.setStock(product.getStock() - 1);
            if (productDao.updateById(product) == 0) {
                throw new CustomizeException("更新商品库存失败");
            }

            // 如果用户是 陈犬犬 则向微信推送消息
            if (user.getNickname().equals("陈犬犬")) {
                String url = "https://sctapi.ftqq.com/SCT27909TyuqOMoLZ4eWkTuOVDKGjRTB3.send";
                HashMap<String, Object> paramMap = new HashMap<>();
                paramMap.put("title", "早睡打卡助手");
                paramMap.put("desp", "用户[" + user.getNickname() + "]兑换了商品[" + product.getName() + "]");

                // 发送 POST 请求
                String res = HttpUtil.post(url, JSONObject.toJSONString(paramMap), 10000);
                log.info("陈犬犬微信推送结果：{}", res);
            }

            return AjaxResult.success();
        } finally {
            // 删除锁
            stringRedisTemplate.delete(redisKey);
        }
    }

    @Override
    public PageQueryInfo<List<RecordQueryAllVo>> getAll(PageQueryParamVo pageQueryParamVo) {
        IPage<RecordQueryAllVo> page =
                this.baseMapper.getAll(new Page<>(pageQueryParamVo.getPageNum(),
                        pageQueryParamVo.getPageSize()), StpUserUtil.getLoginIdAsLong());


        return PageQueryInfo.of(page.getRecords(), page.getTotal());
    }
}
